package com.atguign.gulimall.ware.service.impl;

import com.atguign.gulimall.ware.dao.WareSkuDao;
import com.atguign.gulimall.ware.entity.WareOrderTaskDetailEntity;
import com.atguign.gulimall.ware.entity.WareOrderTaskEntity;
import com.atguign.gulimall.ware.entity.WareSkuEntity;
import com.atguign.gulimall.ware.feign.MemberFeifnService;
import com.atguign.gulimall.ware.feign.ProductFeifnService;
import com.atguign.gulimall.ware.service.WareOrderTaskDetailService;
import com.atguign.gulimall.ware.service.WareOrderTaskService;
import com.atguign.gulimall.ware.service.WareSkuService;
import com.atguign.gulimall.ware.vo.*;
import com.atguigu.common.to.SkuInfoEntityTo;
import com.atguigu.common.to.mq.StockDetailTo;
import com.atguigu.common.to.mq.StockLockedTo;
import com.atguigu.common.utils.PageUtils;
import com.atguigu.common.utils.Query;
import com.atguigu.common.utils.R;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.Data;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;

import java.math.BigDecimal;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service("wareSkuService")
public class WareSkuServiceImpl extends ServiceImpl<WareSkuDao, WareSkuEntity> implements WareSkuService {

    @Autowired
    private ProductFeifnService productFeifnService;
    @Autowired
    MemberFeifnService memberFeifnService;
    @Autowired
    private WareSkuDao wareSkuDao;
    @Autowired
    private WareOrderTaskService orderTaskService;
    @Autowired
    private WareOrderTaskDetailService orderTaskDetailService;
    @Autowired
    RabbitTemplate rabbitTemplate;




    @Override
    public PageUtils queryPage(Map<String, Object> params) {

        LambdaQueryWrapper<WareSkuEntity> wareSkuEntityLambdaQueryWrapper = new LambdaQueryWrapper<>();
        String skuId = (String) params.get("skuId");
        if (StringUtils.hasText(skuId)) {
            wareSkuEntityLambdaQueryWrapper.eq(WareSkuEntity::getSkuId, skuId);
        }
        String wareId = (String) params.get("wareId");
        if (StringUtils.hasText(wareId)) {
            wareSkuEntityLambdaQueryWrapper.eq(WareSkuEntity::getWareId, wareId);
        }
        IPage<WareSkuEntity> page = this.page(
                new Query<WareSkuEntity>().getPage(params),
                wareSkuEntityLambdaQueryWrapper
        );

        return new PageUtils(page);
    }

    @Transactional
    @Override
    public void addStock(Long skuId, Long wareId, Integer skuNum) {
        Long l = baseMapper.selectCount(new LambdaQueryWrapper<WareSkuEntity>()
                .eq(WareSkuEntity::getSkuId, skuId)
                .eq(WareSkuEntity::getWareId, wareId));
        if (l == 0) {
            WareSkuEntity wareSkuEntity = new WareSkuEntity();
            wareSkuEntity.setWareId(wareId);
            wareSkuEntity.setSkuId(skuId);
            wareSkuEntity.setStock(skuNum);
            R r = productFeifnService.infoSkuinfo(skuId);
            SkuInfoEntityTo skuInfo = R.toPoJo(r.get("skuInfo"), SkuInfoEntityTo.class);
//            JSONObject jsonObject = JSONObject.parseObject(JSON.toJSONString(r.get("skuInfo")));
//            SkuInfoEntityTo skuInfo =  JSONObject.toJavaObject(jsonObject, SkuInfoEntityTo.class);
            wareSkuEntity.setSkuName(skuInfo.getSkuName());
            baseMapper.insert(wareSkuEntity);
        } else baseMapper.addStock(skuId, wareId, skuNum);
    }

    /**
     * 查看库存
     *
     * @param skuIds
     * @return
     */
    @Override
    public List<SkuHasStockTo> getSkusHasStock(List<Long> skuIds) {
        return baseMapper.selectList(new LambdaQueryWrapper<WareSkuEntity>()
                        .in(WareSkuEntity::getSkuId, skuIds))
                .stream()
                .map(item -> {
                    SkuHasStockTo skuHasStockTo = new SkuHasStockTo();
                    skuHasStockTo.setSkuId(item.getSkuId());
                    skuHasStockTo.setStock(item.getStock() - item.getStockLocked());
                    return skuHasStockTo;
                }).collect(Collectors.toList());
    }

    @Override
    public FareVo getFare(Long attrId) {
        R info = memberFeifnService.info(attrId);
        FareVo fareVo = new FareVo();
        if (info.getCode() == 0) {
            MemberReceiveAddressEntityVo memberReceiveAddress = R.toPoJo(info.get("memberReceiveAddress"), MemberReceiveAddressEntityVo.class);
            if (memberReceiveAddress != null) {
                String substring = memberReceiveAddress.getPhone().substring(memberReceiveAddress.getPhone().length() - 2);
                fareVo.setAddress(memberReceiveAddress);
                fareVo.setFare(new BigDecimal(substring));

                return fareVo;
            }
        }
        throw new RuntimeException("没有找到用户信息");
    }
    @Transactional
    @Override
    public Boolean orderLockStock(WareSkuLockVo vo) {
        //TODO 订单锁库存详细信息
        WareOrderTaskEntity wareOrderTaskEntity = new WareOrderTaskEntity();
        wareOrderTaskEntity.setOrderSn(vo.getOrderSn());
        orderTaskService.save(wareOrderTaskEntity);


        //查找库存
        List<OrderItemVo> locks = vo.getLocks();
        List<SkuWareHasStock> collect = locks.stream().map(item -> {
            SkuWareHasStock skuWareHasStock = new SkuWareHasStock();
            skuWareHasStock.setSkuId(item.getSkuId());
            List<Long> wareId = this.baseMapper.listWareIdHasSkuStock(item.getSkuId());
            skuWareHasStock.setWareId(wareId);
            skuWareHasStock.setNum(item.getCount());
            return skuWareHasStock;
        }).collect(Collectors.toList());
        //锁定库存
        for (SkuWareHasStock skuWareHasStock : collect) {
            Long skuId = skuWareHasStock.getSkuId();
            List<Long> wareId = skuWareHasStock.getWareId();
            if(wareId==null|| wareId.isEmpty()){
                throw new RuntimeException("商品："+skuId+"无库存");
            }
            boolean lock = false;

            for(Long id:wareId){
                Long i = wareSkuDao.lockSkuStock(skuId, id, skuWareHasStock.getNum());
                if(i!=0){
                    lock=true;
                    //TODO 保存工单详情开启解锁库存延时队列
                    WareOrderTaskDetailEntity wareOrderTaskDetailEntity = new WareOrderTaskDetailEntity(null, skuId, null, skuWareHasStock.getNum(), wareOrderTaskEntity.getId(), id, 1);
                    orderTaskDetailService.save(wareOrderTaskDetailEntity);
                    StockLockedTo stockLockedTo = new StockLockedTo();
                    stockLockedTo.setId(wareOrderTaskEntity.getId());
                    StockDetailTo stockDetailTo = new StockDetailTo();
                    BeanUtils.copyProperties(wareOrderTaskDetailEntity,stockDetailTo );
                    stockLockedTo.setDeatail(stockDetailTo);
                    rabbitTemplate.convertAndSend("stock-event-exchange", "stock.locked", stockLockedTo);
                    break;
                }
            }
            if(!lock){
                throw new RuntimeException("商品："+skuId+"无库存");
            }
        }



        return true;
    }

    @Data
    static class SkuWareHasStock {
        private Long skuId;
        private Integer num;
        private List<Long> wareId;
    }

}